package com.hit.basmath.interview.top_interview_questions.medium_collection.design;

import com.hit.common.TreeNode;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * 297. 二叉树的序列化与反序列化
 * <p>
 * 序列化是将一个数据结构或者对象转换为连续的比特位的操作，进而可以将转换后的数据存储在一个文件或者内存中，同时也可以通过网络传输到另一个计算机环境，采取相反方式重构得到原数据。
 * <p>
 * 请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑，你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
 * <p>
 * 示例: 
 * <p>
 * 你可以将以下二叉树：
 * <p>
 * 1
 * / \
 * 2   3
 * / \
 * 4   5
 * <p>
 * 序列化为 "[1,2,3,null,null,4,5]"
 * <p>
 * 提示: 这与 LeetCode 目前使用的方式一致，详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式，你也可以采用其他的方法解决这个问题。
 * <p>
 * 说明: 不要使用类的成员 / 全局 / 静态变量来存储状态，你的序列化和反序列化算法应该是无状态的。
 */
public class _297 {
    public class Codec {
        // 序列化
        public String serialize(TreeNode root) {
            return serializeHelper(root, "");
        }

        // 反序列化
        public TreeNode deserialize(String data) {
            String[] dataArray = data.split(",");
            List<String> dataList = new LinkedList<>(Arrays.asList(dataArray));
            return deserializeHelper(dataList);
        }

        private String serializeHelper(TreeNode root, String str) {
            if (root == null) {
                str += "null,";
            } else {
                str += String.valueOf(root.val) + ",";
                str = serializeHelper(root.left, str);
                str = serializeHelper(root.right, str);
            }
            return str;
        }

        private TreeNode deserializeHelper(List<String> dataList) {
            if (dataList.get(0).equals("null")) {
                dataList.remove(0);
                return null;
            }
            TreeNode root = new TreeNode(Integer.valueOf(dataList.get(0)));
            dataList.remove(0);
            root.left = deserializeHelper(dataList);
            root.right = deserializeHelper(dataList);
            return root;
        }
    }
}
